package com.arica.project;

import com.alibaba.fastjson.JSONObject;
import com.arica.project.elacticsearch.domain.CrudEsDemo;
import com.arica.project.elacticsearch.domain.CrudEsDemoSearchDTO;
import com.arica.project.elacticsearch.domain.CrudEsSerarchReq;
import com.arica.project.elacticsearch.service.CrudEsApiService;
import org.frameworkset.elasticsearch.ElasticSearchException;
import org.frameworkset.elasticsearch.boot.BBossESStarter;
import org.frameworkset.elasticsearch.client.ClientInterface;
import org.frameworkset.elasticsearch.entity.ESDatas;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;

/**
 * elasticsearch 增删改查 示例  方法实现
 *
 * @author soo
 */
@Service
@org.apache.dubbo.config.annotation.Service(timeout = 3000, retries = 3, cluster="failfast")
public class CrudEsApiServiceImpl implements CrudEsApiService {

    private Logger logger = LoggerFactory.getLogger(CrudEsApiServiceImpl.class);
    @Autowired
    private BBossESStarter bbossESStarterDefault;

    //DSL config file path
    private String mappath = "esmapper/crudEsDsl.xml";

    @Override
    public void createCrudEsIndex() {

        //Create a client tool to load configuration files, single instance multithreaded security
        ClientInterface clientUtil = bbossESStarterDefault.getConfigRestClient(mappath);
        try {
            //To determine whether the indice demo exists, it returns true if it exists and false if it does not
            boolean exist = clientUtil.existIndice("demo");

            //Delete mapping if the indice demo already exists
            if(exist) {
                String r = clientUtil.dropIndice("demo");
                logger.debug("clientUtil.dropIndice(\"demo\") response:"+r);

            }
            //Create index demo
            clientUtil.createIndiceMapping("demo",//The indice name
                    "createCrudEsIndex");//Index mapping DSL script name, defined createDemoIndice in esmapper/demo.xml

            String demoIndice = clientUtil.getIndice("demo");//Gets the newly created indice structure
            logger.info("after createIndiceMapping clientUtil.getIndice(\"demo\") response:"+demoIndice);
        } catch (ElasticSearchException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    @Override
    public void editCrudEsDoc(CrudEsDemo demo) {
        //Build a create/modify/get/delete document client object, single instance multi-thread security
        ClientInterface clientUtil = bbossESStarterDefault.getRestClient();
        //Build an object as index document
        demo = CrudEsDemo.build(demo);
        //Add the document and force refresh
        String response = clientUtil.addDocument("demo",//indice name
                demo,"refresh=true");
        logger.info("编辑索引文档数据结果：{}", response);
    }

    @Override
    public void deleteCrudEsDoc(CrudEsDemo crudEsDemo) {
        //Build a create/modify/get/delete document client object, single instance multi-thread security
        ClientInterface clientUtil = bbossESStarterDefault.getRestClient();
        //Batch delete documents
        clientUtil.deleteDocuments("demo",//indice name
                new String[]{crudEsDemo.getDemoId().toString()});//Batch delete document ids
    }

    @Override
    public List<CrudEsDemoSearchDTO> searchCrudEsDoc(CrudEsSerarchReq req) {

        ClientInterface clientUtil = bbossESStarterDefault.getConfigRestClient(mappath);

//        HashMap<String, String> params = new HashMap<>();
//        params.put("startTime", "10");
//        params.put("endTime", "1000000000000000");
//        params.put("condition", "晶");
//
//        ESDatas<CrudEsDemo> crudEsDemoESDatas = clientUtil.searchList("demo" + "/_search", "testHighlightSearch", params, CrudEsDemo.class);

//        return crudEsDemoESDatas.getDatas();


        //Set query conditions, pass variable parameter values via map,key for variable names in DSL
        //There are four variables in the DSL:
        //        applicationName1
        //        applicationName2
        //        startTime
        //        endTime
        Map<String,Object> params = new HashMap<String,Object>();
        //Set the values of applicationName1 and applicationName2 variables
        params.put("applicationName1","blackcatdemo2");
        params.put("applicationName2","blackcatdemo3");
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //Set the time range, and accept the long value as the time parameter
        try {
            params.put("startTime",dateFormat.parse("2017-09-02 00:00:00").getTime());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        params.put("endTime",new Date().getTime());


        //Execute the query
        ESDatas<CrudEsDemo> esDatas =  //ESDatas contains a collection of currently retrieved records, up to 1000 records, specified by the size attribute in the DSL
                clientUtil.searchList("demo/_search",//demo as the indice, _search as the search action
                        "searchDatas",//DSL statement name defined in esmapper/demo.xml
                        params,//Query parameters
                        CrudEsDemo.class);//Data object type Demo returned

        List<CrudEsDemoSearchDTO> res = new ArrayList<>();

        esDatas.getDatas().stream().forEach(e->{
            CrudEsDemoSearchDTO target = new CrudEsDemoSearchDTO();
            BeanUtils.copyProperties(e, target);
            res.add(target);
        });

        return res;
    }
}
